package com.rou.im.framework.core.log;

/**
 * <p></p>
 *
 * @author GaoShuangWen
 * @since 2020-05-13 22:51
 */

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;

public class JLogger {
    private static final String LINESEPARATOR =  System.getProperty("line.separator");

    private Writer writer;
    private File logFile;
    private long timingBase = 0;        //当前日志文件的基准时间（单位：毫秒）
    /**
     * 生成新日志文件的时间间隔,单位毫秒。默认值1小时
     */
    private long timingSpace = 3600000;

    public long getTimingSpace() {
        return timingSpace;
    }

    public void setTimingSpace(long timingSpace) {
        this.timingSpace = timingSpace;
    }

    /**
     * 日志文件名的时间格式
     */
    final private SimpleDateFormat pathFormat;
    private String errString = "";
    private final StringBuilder sb = new StringBuilder();

    public JLogger(String pathTemple) {
        this.pathFormat = new SimpleDateFormat(pathTemple);
    }

    public final String getErrString() {
        return this.errString;
    }
    /**
     * 创建一个新的日志文件
     * @param t 创建新日志文件的时间
     * @throws IOException
     */
    private void createNewLogFile(long t) throws IOException {
        //根据生成新日志文件的时间间隔，将时间t与之对齐。
        this.timingBase = (t / this.timingSpace) * this.timingSpace;
        // 生成新日志文件名
        logFile = new File(this.pathFormat.format(new Date(this.timingBase)));

        //更换新的日志文件之后，一定要关闭前一个日志文件的FileWriter对象，否则，日志会继续写入前一个日志文件。
        if (this.writer != null) {
            this.writer.close();
            this.writer = null;
        }
    }
    /**
     * 检查当前日志文件是否存在，如果不存在，则创建新的日志文件
     * @return true：日志文件存在或创建新的日志文件成功；false：创建新日志文件失败。
     * @throws IOException
     */
    private boolean checkFile() throws IOException {
        //检查日志文件是否存在，如果不存在，则创建日志文件
        if (!logFile.exists()) {
            //检查保存日志文件的目录是否存在，如果不存在，则为日志文件创建目录
            File pf = logFile.getParentFile();
            if (!pf.exists()) {
                if (!pf.mkdirs()) {
                    this.errString = "JLogger can_not create path " + pf.getPath();
                    return false;
                }
            }
            //更换新的日志文件之后，一定要关闭前一个日志文件的FileWriter对象，否则，日志会继续写入前一个日志文件。
            if (this.writer != null) {
                this.writer.close();
                this.writer = null;
            }
        }

        //检查写日志的FileWriter对象是否存在，如果不存在，则生成一个FileWriter对象。
        if (this.writer == null) {
            this.writer = new FileWriter(this.logFile, true);
        }
        return true;
    }
    /**
     * 向日志文件中添加日志
     * @param s 要添加的日志内容
     * @return true：添加成功，false：添加失败
     * @throws IOException
     */
    private boolean append(long t,String s) throws IOException {
        if(s == null || s.isEmpty()) return true;
        //首先检查是否需要创建新的日志文件
        if (t - this.timingBase >= this.timingSpace) {
            this.createNewLogFile(t);
        }
        //检查日志文件是否存在
        if (!this.checkFile()) {
            return false;
        }
        //写入日志数据
        this.writer.write(s);
        this.writer.write(LINESEPARATOR);
        this.writer.flush();
        return true;
    }
    /**
     * 写日志
     * @param ss 包含日志内容的集合
     * @return true：写日志成功；false：写日志失败
     * @throws IOException
     */
    public boolean append(long t,Object ...ss) throws IOException {
        sb.setLength(0);
        for (Object s : ss) {
            sb.append(s);
        }
        return append(t,sb.toString());
    }
}
